using System.Diagnostics;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace DeviceDataGenerator
{
    /// <summary>
    /// 系统资源监控器
    /// 负责监控CPU和内存使用情况
    /// </summary>
    public class SystemResourceMonitor : IDisposable
    {
        private readonly Process _currentProcess;
        private readonly Timer _refreshTimer;
        private readonly object _lockObject = new object();
        
        // 移除volatile关键字，使用lock保护
        private double _currentCpuUsage;
        private long _currentMemoryUsage;
        private bool _disposed = false;
        
        // CPU监控相关（跨平台兼容）
        private DateTime _lastCpuTime = DateTime.UtcNow;
        private TimeSpan _lastTotalProcessorTime;
        private bool _isFirstCpuReading = true;

        public SystemResourceMonitor(int refreshIntervalMs = 1000)
        {
            _currentProcess = Process.GetCurrentProcess();
            _lastTotalProcessorTime = _currentProcess.TotalProcessorTime;
            
            // 启动定时器定期刷新数据
            _refreshTimer = new Timer(RefreshResourceUsage, null, 0, refreshIntervalMs);
        }

        /// <summary>
        /// 获取当前CPU使用率（百分比）
        /// </summary>
        public double CurrentCpuUsage 
        { 
            get 
            { 
                lock (_lockObject) 
                { 
                    return _currentCpuUsage; 
                } 
            } 
        }

        /// <summary>
        /// 获取当前内存使用量（字节）
        /// </summary>
        public long CurrentMemoryUsage 
        { 
            get 
            { 
                lock (_lockObject) 
                { 
                    return _currentMemoryUsage; 
                } 
            } 
        }

        /// <summary>
        /// 获取当前内存使用量（MB）
        /// </summary>
        public double CurrentMemoryUsageMB 
        { 
            get 
            { 
                lock (_lockObject) 
                { 
                    return _currentMemoryUsage / (1024.0 * 1024.0); 
                } 
            } 
        }

        /// <summary>
        /// 定期刷新资源使用情况
        /// </summary>
        private void RefreshResourceUsage(object? state)
        {
            try
            {
                var currentTime = DateTime.UtcNow;
                
                lock (_lockObject)
                {
                    // 更新CPU使用率（使用进程 CPU 时间计算）
                    _currentProcess.Refresh();
                    var currentTotalProcessorTime = _currentProcess.TotalProcessorTime;
                    
                    if (!_isFirstCpuReading)
                    {
                        var cpuUsedMs = (currentTotalProcessorTime - _lastTotalProcessorTime).TotalMilliseconds;
                        var totalMsPassed = (currentTime - _lastCpuTime).TotalMilliseconds;
                        var cpuUsageTotal = cpuUsedMs / (Environment.ProcessorCount * totalMsPassed);
                        
                        _currentCpuUsage = cpuUsageTotal * 100.0;
                        
                        // 限制在合理范围内
                        if (_currentCpuUsage < 0) _currentCpuUsage = 0;
                        if (_currentCpuUsage > 100) _currentCpuUsage = 100;
                    }
                    else
                    {
                        _isFirstCpuReading = false;
                    }
                    
                    _lastCpuTime = currentTime;
                    _lastTotalProcessorTime = currentTotalProcessorTime;
                    
                    // 更新内存使用量
                    _currentMemoryUsage = _currentProcess.WorkingSet64;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"警告: 更新资源监控数据时出错: {ex.Message}");
            }
        }

        /// <summary>
        /// 获取资源使用快照
        /// </summary>
        /// <returns></returns>
        public ResourceSnapshot GetSnapshot()
        {
            lock (_lockObject)
            {
                return new ResourceSnapshot
                {
                    CpuUsagePercent = _currentCpuUsage,
                    MemoryUsageBytes = _currentMemoryUsage,
                    Timestamp = DateTime.Now
                };
            }
        }

        public void Dispose()
        {
            if (!_disposed)
            {
                _refreshTimer?.Dispose();
                _currentProcess?.Dispose();
                _disposed = true;
            }
        }
    }

    /// <summary>
    /// 资源使用快照
    /// </summary>
    public class ResourceSnapshot
    {
        public double CpuUsagePercent { get; set; }
        public long MemoryUsageBytes { get; set; }
        public DateTime Timestamp { get; set; }
        
        public double MemoryUsageMB => MemoryUsageBytes / (1024.0 * 1024.0);
    }

    /// <summary>
    /// 千次移动平均计算器
    /// 用于计算最近1000次操作的移动平均值
    /// </summary>
    /// <typeparam name="T">数值类型</typeparam>
    public class MovingAverage<T> where T : struct, IConvertible
    {
        private readonly Queue<T> _values;
        private readonly int _windowSize;
        private double _sum;

        public MovingAverage(int windowSize = 1000)
        {
            _windowSize = windowSize;
            _values = new Queue<T>(windowSize + 1);
        }

        /// <summary>
        /// 添加新值并计算移动平均
        /// </summary>
        /// <param name="value">新值</param>
        public void Add(T value)
        {
            var doubleValue = Convert.ToDouble(value);
            
            if (_values.Count >= _windowSize)
            {
                var oldValue = _values.Dequeue();
                _sum -= Convert.ToDouble(oldValue);
            }

            _values.Enqueue(value);
            _sum += doubleValue;
        }

        /// <summary>
        /// 获取当前移动平均值
        /// </summary>
        public double Average => _values.Count > 0 ? _sum / _values.Count : 0.0;

        /// <summary>
        /// 获取当前窗口大小
        /// </summary>
        public int Count => _values.Count;

        /// <summary>
        /// 清空数据
        /// </summary>
        public void Clear()
        {
            _values.Clear();
            _sum = 0;
        }
    }
}